/**
 * @Description: 权限指令 第三版本
 * @Author bianpengfei
 * @create 2022/11/25 18:19
 * @example
 * <VAuth3 :code='`xxxx`'> 你的组件 </VAuth3>
 */
import useMenuStore from '@store/use-menu-store'
import useAppStore from '@store/use-app-store.ts'
import { isString, isPlainObject, isArray, isNumber } from 'sf-utils2' // utils包
import setting from '@/setting'
import { computed, defineComponent, type PropType } from 'vue'

let _menuStore: ReturnType<typeof useMenuStore>, _appStore: ReturnType<typeof useAppStore>

/**
 * 获取code值
 * @param {string} code code码
 */
export function getCode(code) {
  _appStore ||= useAppStore()
  code = String(code)
  const list = code.split('|').filter(Boolean)
  if (list.length == 1) {
    // 只有一个
    const path = _appStore.router.currentRoute?.path
    code = path + `|${list[0]}`
  }
  // } else if (list.length == 2) {
  //   code =
  // }
  // if (!/^\//.test(code)) {
  //   // 如果非绝对路径开头
  //   const path = appStore.router.path
  //   code = path + `|${code}`
  // }
  return code
}

/**
 * 简单的判断单个code是否有权限访问 基础
 * @param {string} code
 * @return {boolean}
 */
function checkCodePermissionBase(code) {
  _menuStore ||= useMenuStore()
  console.log('_menuStore', _menuStore)
  const { _authButtonListObjByPermissionCode } = _menuStore
  const absCode = getCode(code)
    .trim()
    .replace(/\(.*?\)$/, '')
    .replace(/（.*?）$/, '')
  const splitArr = absCode.split('|').filter(Boolean)
  const [pathName, permissionCode] = splitArr
  if (!pathName || !permissionCode) return false

  // 以前是 path + permissionCode, 生成唯一key
  // const authObj = _authButtonListObjByCode[absCode] || _authButtonListObjByCode[permissionCode]
  // if (authObj?.__menuNode__) {
  //   return !!authObj?.__menuNode__.exp?.test?.(pathName)
  // }
  // return false
  return !!_authButtonListObjByPermissionCode[permissionCode]
}

/**
 * 检查code 是否可以有权限访问
 * @param {string|Array|object} code
 * @return {boolean}
 * @example
 * checkCodePermission('10001')
 * checkCodePermission(['10001', '10002'])
 */
export function checkCodePermission(code) {
  if (setting.isSkipButtonAuth) return true

  let hasPermission = false

  if (code) {
    if (isString(code) || isNumber(code)) {
      // 字符串
      hasPermission = checkCodePermissionBase(code)
    } else if (isPlainObject(code)) {
      // 普通对象类型
      hasPermission = checkCodePermissionBase(code?.code)
    } else if (isArray(code)) {
      // 数组类型
      hasPermission = code.some((o) => checkCodePermissionBase(o))
    }
  }
  return hasPermission
}

/**
 * 权限组件
 * @example
 * ```vue
 * <VAuth :code='xxxx'>xxxx</VAuth>
 * ```
 * @type {DefineComponent<{code: {default: string, type: {new(...args: any[]): (String | {code: string} | (string[] & {}))} | {(): (String | {code: string} | string[])} | PropConstructor<String | {code: string} | string[]>[]}}, () => any, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, Record<string, any>, string>}
 */
export const VAuth = defineComponent({
  props: {
    code: {
      type: [String, Object, Array] as PropType<String | { code: string } | string[]>,
      default: ''
    }
  },
  setup(props, { slots }) {
    const hasPermission = computed(() => checkCodePermission(props.code))
    return () => {
      return hasPermission.value ? slots?.default?.() : null
    }
  }
})

/*eslint-disable*/
export default {
  beforeMount(el) {},
  updated(el) {},
  beforeUnmount(el) {},

  install(app) {
    app.component('VAuth', VAuth)
  }
}
